# -- coding: utf-8 --
import glob
import os
import random
import sys
from shutil import copyfile
import re
import define
import pdb
'''
文件操作类
'''
def copy_all(from_dir, to_dir, file_names, name_pattern=None):
    if name_pattern is not None:
        print('copying files with pattern: %s' % name_pattern)
        file_paths = glob.glob(os.path.join(from_dir, name_pattern))
        total_file_count = len(file_paths)
        print('Files found: %d' % total_file_count)
        for index in range(total_file_count):
            copyfile(file_paths[index], to_dir + utils.get_filename_from_path(file_paths[index]))
            if not index % 1000:
                print('copied %d of %d files.' % (index, total_file_count))
                sys.stdout.flush()
    else:
        total_file_count = len(file_names)
        print('copying all files: %d' % total_file_count)
        for index in range(total_file_count):
            copyfile(from_dir +'/'+ file_names[index], to_dir +'/'+ file_names[index])
            if not index % 1000:
                print('copied %d of %d files.' % (index, total_file_count))
                sys.stdout.flush()

def copy_files(from_dir, to_dir, name_pattern=None, n_sample=None):
    print('copy_files() - From: %s' % from_dir)
    print('copy_files() -   To: %s' % to_dir)
    file_names = os.listdir(from_dir)
    file_names = sorted(file_names)
    if n_sample is None:
        copy_all(from_dir, to_dir, file_names, name_pattern)
    else:
        assert len(file_names) >= n_sample, "Not enough files to copy. available: %d, requested: %d" % \
                                            (len(file_names), n_sample)

        if name_pattern is None:
            shuffled_index = list(range(len(file_names)))
            random.seed(12345)
            random.shuffle(shuffled_index)
            for index in range(n_sample):
                copyfile(from_dir + file_names[shuffled_index[index]], to_dir + file_names[shuffled_index[index]])
                if not index % 1000:
                    print('copied %d of %d files.' % (index, n_sample))
                    sys.stdout.flush()
        else:
            print('copying files with pattern: %s' % name_pattern)
            file_paths = glob.glob(os.path.join(from_dir, name_pattern))
            total_file_count = len(file_paths)
            print('Files found: %d' % total_file_count)
            assert len(file_paths) >= n_sample, "Not enough files to copy with requested pattern. available: %d, " \
                                                "requested: %d" % (total_file_count, n_sample)
            file_paths = file_paths[:n_sample]
            for index in range(n_sample):
                copyfile(file_paths[index], to_dir + utils.get_filename_from_path(file_paths[index]))
                if not index % 1000:
                    print('copied %d of %d files.' % (index, n_sample))
                    sys.stdout.flush()

def move_all(from_dir, to_dir, file_names, name_pattern):
    if name_pattern is not None:
        print('moving files with pattern: %s' % name_pattern)
        file_paths = glob.glob(os.path.join(from_dir, name_pattern))
        total_file_count = len(file_paths)
        print('Files found: %d' % total_file_count)
        for index in range(total_file_count):
            os.rename(file_paths[index], to_dir + utils.get_filename_from_path(file_paths[index]))
            if not index % 1000:
                print('moved %d of %d files.' % (index, total_file_count))
                sys.stdout.flush()
    else:
        total_file_count = len(file_names)
        print('moving all files: %d' % total_file_count)
        for index in range(total_file_count):
            os.rename(from_dir + file_names[index], to_dir + file_names[index])
            if not index % 1000:
                print('moved %d of %d files.' % (index, total_file_count))
                sys.stdout.flush()

def move_files(from_dir, to_dir, name_pattern=None, n_sample=None):
    print('move_files() - From: %s' % from_dir)
    print('move_files() -   To: %s' % to_dir)
    file_names = os.listdir(from_dir)
    file_names = sorted(file_names)
    if n_sample is None:
        move_all(from_dir, to_dir, file_names, name_pattern)
    else:
        assert len(file_names) >= n_sample, "Not enough files to move. available: %d, requested: %d" % \
                                            (len(file_names), n_sample)
        if name_pattern is None:
            shuffled_index = list(range(len(file_names)))
            random.seed(12345)
            random.shuffle(shuffled_index)
            # print(sorted(shuffled_index[:n_sample]))
            for index in range(n_sample):
                os.rename(from_dir + file_names[shuffled_index[index]], to_dir + file_names[shuffled_index[index]])
                if not index % 1000:
                    print('moved %d of %d files.' % (index, n_sample))
                    sys.stdout.flush()
        else:
            print('moving files with pattern: %s' % name_pattern)
            file_paths = glob.glob(os.path.join(from_dir, name_pattern))
            total_file_count = len(file_paths)
            print('Files found: %d' % total_file_count)
            assert len(file_paths) >= n_sample, "Not enough files to move with requested pattern. available: %d, " \
                                                "requested: %d" % (total_file_count, n_sample)
            file_paths = file_paths[:n_sample]
            for index in range(n_sample):
                os.rename(file_paths[index], to_dir + utils.get_filename_from_path(file_paths[index]))
                if not index % 1000:
                    print('moved %d of %d files.' % (index, n_sample))
                    sys.stdout.flush()

def delete_all(from_dir, file_names, name_pattern):
    if name_pattern is not None:
        print('deleting files with pattern: %s' % name_pattern)
        file_paths = glob.glob(os.path.join(from_dir, name_pattern))
        total_file_count = len(file_paths)
        print('Files found: %d' % total_file_count)
        for index in range(total_file_count):
            os.remove(file_paths[index])
            if not index % 1000:
                print('deleted %d of %d files.' % (index, total_file_count))
                sys.stdout.flush()
    else:
        total_file_count = len(file_names)
        print('deleting all files : %d' % total_file_count)
        for index in range(total_file_count):
            os.remove(from_dir + file_names[index])
            if not index % 1000:
                print('deleted %d of %d files.' % (index, total_file_count))
                sys.stdout.flush()

def delete_files(from_dir, name_pattern=None, n_sample=None):
    print('delete_files() - From: %s' % from_dir)
    file_names = os.listdir(from_dir)
    file_names = sorted(file_names)
    if n_sample is None:
        delete_all(from_dir, file_names, name_pattern)
    else:
        assert len(file_names) >= n_sample, "Not enough files to delete. available: %d, requested: %d" % \
                                            (len(file_names), n_sample)
        if name_pattern is None:
            shuffled_index = list(range(len(file_names)))
            random.seed(12345)
            random.shuffle(shuffled_index)
            for index in range(n_sample):
                os.remove(from_dir + file_names[shuffled_index[index]])
                if not index % 1000:
                    print('deleted %d of %d files.' % (index, n_sample))
                    sys.stdout.flush()
        else:
            print('deleting files with pattern: %s' % name_pattern)
            file_paths = glob.glob(os.path.join(from_dir, name_pattern))
            total_file_count = len(file_paths)
            print('Files found: %d' % total_file_count)
            assert len(file_paths) >= n_sample, "Not enough files to delete with requested pattern. available: %d, " \
                                                "requested: %d" % (total_file_count, n_sample)
            file_paths = file_paths[:n_sample]
            for index in range(n_sample):
                os.remove(file_paths[index])
                if not index % 1000:
                    print('deleted %d of %d files.' % (index, n_sample))
                    sys.stdout.flush()

def rename_forDir(slideDir, prefix_flag=None, maskDir=None, xmlDir=None, exclude_Dir=None):
    i = 1
    if prefix_flag == 'Tumor':
        prefix = "Tumor_"
    elif prefix_flag == 'Normal':
        prefix = "Nomal_"
    elif prefix_flag == 'Test':
        prefix = "Test_"
    else:
        raise ValueError('prefix_flag must be ''Train/Normal/Test''')
    if prefix_flag != 'Tumor' or len(os.listdir(slideDir)) == len(os.listdir(maskDir)):
        for slidefile in os.listdir(slideDir):
            slidepath = os.path.join(slideDir, slidefile) #get the path of the file 
            filetype = slidepath.split('.')[-1]
            new_slidename = prefix + '%03d'%i + '.' + filetype #creat new name
            # print slideDir+'/'+new_slidename,slidefile
            if not os.path.exists(slideDir+'/'+new_slidename) or re.match(prefix,slidefile):
                new_slidepath = os.path.join(slideDir, new_slidename) #which file to be rename
                os.rename(slidepath, new_slidepath) #rename the file

            if not prefix_flag == 'Normal':
                maskfile = slidefile.split('.%s'%filetype)[0] + '.tif'
                maskpath = os.path.join(maskDir, maskfile)
                if os.path.exists(maskpath):
                    new_maskname = prefix + '%03d'%i + '.tif'
                    if not os.path.exists(maskDir+'/'+new_maskname) or re.match(prefix,maskfile):
                        new_maskpath = os.path.join(maskDir, new_maskname)
                        os.rename(maskpath, new_maskpath)
                xmlfile = slidefile.split('.%s'%filetype)[0] + '.xml'
                xmlpath = os.path.join(xmlDir, xmlfile)
                if os.path.exists(xmlpath):
                    new_xmlname = prefix + '%03d'%i + '.xml'
                    if not os.path.exists(xmlDir+'/'+new_xmlname) or re.match(prefix,xmlfile):
                        new_xmlpath = os.path.join(xmlDir, new_xmlname)
                        os.rename(xmlpath, new_xmlpath)

            if exclude_Dir:
                exclude_file = slidefile.split('.%s'%filetype)[0] +'_exclude'+'.tif'
                # print exclude_file
                # pdb.set_trace()
                exclude_path = os.path.join(exclude_Dir, exclude_file)
                new_exclude_name = prefix + '%03d'%i +'_exclude' + '.tif'
                if os.path.exists(exclude_path):
                    if not os.path.exists(exclude_Dir+'/'+new_exclude_name or re.match(prefix,exclude_file)):
                        new_exclude_path = os.path.join(exclude_Dir, new_exclude_name)
                        os.rename(exclude_path, new_exclude_path)
            i += 1
        print ('Finish')
    else:
        print ('the number of slide files don\'t match the mask one')
        return False

def search(search_dir, name_pattern='*'):
    file_paths = glob.glob(os.path.join(search_dir, name_pattern))
    print("Found %d files with pattern '%s' into '%s'." % (len(file_paths), name_pattern, search_dir))
    return len(file_paths)

def get_filename_from_path(file_path):
    path_tokens = file_path.split('/')
    filename = path_tokens[path_tokens.__len__() - 1].split('.')[0]
    return filename

def get_filefromtxt(search_dir):
    txt_dir = search_dir+'/source_list'
    for filename in os.listdir(txt_dir):
        img_class = filename[:2]
        to_dir = search_dir+img_class
        txt_file_path = os.path.join(txt_dir, filename)
        txt_file = open(txt_file_path ,'r')
        fp_recs = txt_file.readlines()
        fp_path = [item.split(',')[-1] for item in fp_recs]
        total_file_count = len(fp_path)
        print('copying files ...: ')         
        print('Files found: %d' % total_file_count)
        for index in range(total_file_count):
            dst = to_dir + '/' + define.get_filename_from_path(fp_path[index])
            copyfile(fp_path[index].split('\n')[0], dst)
            if not index % 1000:
                print('copied %d of %d files.' % (index, total_file_count))
                sys.stdout.flush()

if __name__ == '__main__':
    get_filefromtxt('/home/ramsley/DataSet/prostate/fpfn/')
